﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace LightCAD.Core.Elements
{
    public class LcBasePoint : LcElement
    {
        public Vector2d Point { get; set; }
        public double  Radius { get; set; }

        public LcBasePoint()
        {
            this.Type = BuiltinElementType.BasePoint;
        }

        public LcBasePoint(Vector2d point)
        {
            this.Point = point;
        }

        public override LcElement Clone()
        {
            var clone = Document.CreateObject<LcBasePoint>();
            clone.Copy(this);
            clone.Initilize(this.Document);
            return clone;
        }

        public override void Copy(LcElement src)
        {
            base.Copy(src);
            var basePoint = ((LcBasePoint)src);
            this.Point = basePoint.Point;
        }
        public void Set(Vector2d? point = null, bool fireChangedEvent = true)
        {
            //PropertySetter:Point,Radius            
            if (!fireChangedEvent)
            {
                if (point != null) this.Point = point.Value;
            }
            else
            {
                bool chg_Point = (point != null && point != this.Point);
                if (chg_Point)
                {
                    OnPropertyChangedBefore(nameof(Point), this.Point, point);
                    var oldValue = this.Point;
                    this.Point = point.Value;
                    OnPropertyChangedAfter(nameof(Point), oldValue, this.Point);
                }
            }
        }
        public override Box2d GetBoundingBox()
        {
            return new Box2d(new Vector2d(this.Point.X - this.Radius, this.Point.Y - this.Radius),
                new Vector2d(this.Point.X + this.Radius, this.Point.Y + this.Radius));
        }
        public override Box2d GetBoundingBox(Matrix3d matrix)
        {
            var mcenter = matrix.MultiplyPoint(this.Point);
            var medge = matrix.MultiplyPoint(this.Point + new Vector2d(0, this.Radius));
            var mradius = Vector2d.Distance(mcenter, medge);

            return new Box2d(new Vector2d(mcenter.X - mradius, mcenter.Y - mradius),
                new Vector2d(mcenter.X + mradius, mcenter.Y + mradius));
        }

        public override bool IntersectWithBox(Polygon2d testPoly, List<RefChildElement> intersectChildren = null)
        {
            
            Box2d thisBox = this.BoundingBox;
            if (!thisBox.IntersectWith(testPoly.BoundingBox))
            {
                return false;
            }
            
            Vector2d start = this.Point + new Vector2d(this.Radius, 0);
            Vector2d end = this.Point - new Vector2d(this.Radius, 0);
            if (GeoUtils.IsPolygonIntersectLine(testPoly.Points,start,end))
            {
                return true;
            }
             start = this.Point + new Vector2d(0, this.Radius);
             end = this.Point - new Vector2d( 0, this.Radius);
            if (GeoUtils.IsPolygonIntersectLine(testPoly.Points, start, end))
            {
                return true;
            }
            if (GeoUtils.IsPolygonIntersectCircle(testPoly.Points, this.Point, this.Radius/3))
            {
                return true;
            }
            if (GeoUtils.IsPolygonIntersectCircle(testPoly.Points, this.Point, (this.Radius/3)*2))
            {
                return true;
            }
            return false;
        }


        public override bool IncludedByBox(Polygon2d testPoly, List<RefChildElement> includedChildren = null)
        {
            //testPoly.IsConvex==false 不是凸多边形的情况目前没有考虑
            Box2d thisBox = this.BoundingBox;
            if (!thisBox.IntersectWith(testPoly.BoundingBox))
            {
                return false;
            }
            return GeoUtils.IsCircleInPolygon(this.Point, this.Radius, testPoly.Points);
        }
    }
}
